import { common, kernel, schema } from '@/ts/base';
import orgCtrl from '@/ts/controller';
import { ICompany, IGroup } from '@/ts/core';
import { formatDate } from '@/utils';
import { IBelong } from '@/utils/excel';
import _ from 'lodash';
import { IMallTemplate } from '../../thing/standard/page/mallTemplate';
import { OrderValidator } from './orderValidator';
import message from '@/utils/message';
import SplitHandler from '@/ts/scripting/core/rule/SplitHandler';

/** 订单接口 */
export interface IOrder extends common.Emitter {
  /** 关键字 */
  key: string;
  /** 归属对象 */
  space: IBelong;
  /** 元数据 */
  metadata: schema.XOrder;
  /** 创建订单 */
  createOrder(products: schema.XProduct[]): Promise<any[]>;
  /** 保存订单 */
  saveOrder(orderItem: schema.XOrder): Promise<void>;
  /** 支付订单 */
  payOrder(order: schema.XOrder): Promise<schema.XOrder | undefined>;
  /** 更新订单 */
  updateOrder(order: schema.XOrder): Promise<schema.XOrder | undefined>;
  /** 取消订单 */
  cancelOrder(orderId: string): Promise<boolean>;
  /** 完成订单 */
  completeOrder(orderId: string): Promise<boolean>;
  /** 创建订单讨论群 */
  createOrderDiscussionChat(sellerId: string, buyerId: string): Promise<any>;
  /** 两者订单讨论群是否存在 */
  hasDiscussionChat(sellerId: string, buyerId: string): Promise<boolean>;
}
export class Order extends common.Emitter implements IOrder {
  constructor(mall: IMallTemplate) {
    super();
    const space = mall.directory.target.space;
    this.space = space;
    this.mall = mall;
    this.platform = mall.directory.target as ICompany | IGroup;
    this.orderValidator = new OrderValidator(space);
    this.chatGroupId = '';
    this.metadata = {} as schema.XOrder;
    this.items = [];
  }
  mall: IMallTemplate;
  items: schema.XProduct[];
  space: IBelong;
  platform: ICompany | IGroup;
  metadata: schema.XOrder;
  chatGroupId: string;
  orderValidator: OrderValidator;

  private collName: string = 'mall-order';

  get key() {
    return this.space.key + '-order';
  }
  // 获取订单讨论群ID
  get getChatGroupId() {
    return this.chatGroupId;
  }

  async createOrder(products: schema.XProduct[]): Promise<any[]> {
    // 根据 归属 字段分组
    const groupedProducts = _.groupBy(products, 'belongId');
    const { id: buyerUserId, name: buyerUserName } = orgCtrl.user.metadata;
    const tasks = Object.entries(groupedProducts).map(async ([key, value]) => {
      try {
        const sellerEntity: schema.XEntity | undefined = this.space.findMetadata(key);
        const now = formatDate(Date.now(), 'yyyy-MM-dd HH:mm:ss.S');
        const totalPrice = this.calculateTotal(value);
        const totalCount = this.calculateCount(value);
        const orderNumber = this.generateOrderNumber();
        const goods = await Promise.all(
          value.map(async (item) => {
            const count = item.carCount || 1;
            const coll = this.mall.directory.resource.genColl('goods-sync');
            const asset = await coll.find([item.id]);
            const newItem: any =
              Array.isArray(asset) && asset.length > 0 ? asset[0] : item;
            return {
              orderNumber, // 订单编号
              purchaseQuantity: count, // 购买数量
              pendingCount: count, // 待处理数量
              id: item.id,
              title: newItem.title,
              name: newItem.title,
              price: newItem.price,
              count: newItem.count,
              remark: newItem.remark,
              belongId: newItem.belongId,
              resource: this.splitOrder({
                ...newItem,
                purchaseQuantity: count,
                pendingCount: count,
              }),
              createUser: newItem.createUser,
              updateUser: newItem.updateUser,
              createTime: newItem.createTime,
              updateTime: newItem.updateTime,
            };
          }),
        );
        const orderItem = {
          id: 'snowId()',
          name: `订单:${orderNumber}`,
          orderNumber: orderNumber, // 订单编号
          mallId: this.mall.id, // 商城id
          mallName: this.mall.name, // 商城名称
          platform: this.platform.metadata.belongId, // 平台方
          seller: key, // 卖方单位id
          sellerName: sellerEntity?.name, // 卖方单位名称
          groupId: this.platform.metadata.id, // 集群id
          buyer: this.space.id, // 买方单位id
          buyerName: this.space.name, // 买方单位名称
          itemList: goods, // 商品集合
          actualPaidPrice: totalPrice, // 实付价
          originalPrice: totalPrice, // 原价
          discountAmount: 0, // 优惠金额
          discount: 0, // 商品折扣
          totalCount: totalCount, // 订单数量
          pendingCount: totalCount, // 待处理订单数量
          totalPrice: totalPrice, // 商品总价
          orderStatus: 'PROCESSING', // 订单状态
          orderTime: now, // 下单时间
          paymentMethod: '', // 支付方式
          transactionId: '', // 支付交易编号
          paymentTime: '', //支付时间
          buyerUserId: buyerUserId, // 购买用户id
          buyerUserName: buyerUserName, // 购买用户名称
          recipientName: '', // 收货人姓名
          recipientPhone: '', // 收货人电话
          deliveryAddress: '', // 收货地址
          buyerRemarks: '', // 下单方留言
          createUser: buyerUserId, // 创建用户
          updateUser: buyerUserId, // 更新用户
          createdTime: now, // 创建时间
          updatedTime: now, // 更新时间
        } as schema.XOrder;

        this.convertToDouble(orderItem, [
          'actualPaidPrice',
          'originalPrice',
          'discountAmount',
          'totalPrice',
        ]);
        const validationResult = this.orderValidator.validateOrder(orderItem);
        if (!validationResult.length) {
          const result = await kernel.createOrder(
            orderItem.platform,
            orderItem.platform,
            [orderItem.platform],
            {
              ...orderItem,
              belongId: orderItem.platform,
            },
          );
          if (result.success) {
            // 买方不等于平台方（避免重复写入订单数据）
            if (this.space.id !== orderItem.platform) {
              await this.saveOrder(orderItem);
            }
            // 卖方不等于平台方（避免重复写入订单数据）
            if (
              orderItem.seller !== orderItem.platform &&
              orderItem.seller !== orderItem.buyer
            ) {
              await kernel.createOrder(
                orderItem.seller,
                orderItem.seller,
                [orderItem.seller],
                {
                  ...orderItem,
                  belongId: orderItem.seller,
                },
              );
            }
          }
          if (result.success) {
            this.mall.shoppingCar.batchRemove(orderItem.itemList);
            await this.mall.directory.resource.templateColl.notity({
              operate: 'mall-change',
              data: this.mall.metadata,
            });
          }
          return { success: result.success, order: orderItem, result: validationResult };
        } else {
          return { success: false, order: orderItem, result: validationResult };
        }
      } catch (error) {
        console.error(`处理订单 ${key} 时发生错误:`, error);
      }
    });

    const results = await Promise.all(tasks);
    const successCount = results.reduce(
      (accumulator, currentValue) => accumulator + (currentValue?.success ? 1 : 0),
      0,
    );
    const errorCount = results.reduce(
      (accumulator, currentValue) => accumulator + (currentValue?.success ? 0 : 1),
      0,
    );
    setTimeout(() => {
      message.info(`下单成功${successCount}个，失败${errorCount}个`);
    }, 1500);
    return results.filter((item) => item !== undefined);
  }
  async saveOrder(orderItem: schema.XOrder): Promise<void> {
    const result = await kernel.collectionInsert(
      this.space.id,
      this.space.belongId,
      this.space.relations,
      this.collName,
      {
        _id: orderItem.orderNumber,
        ...orderItem,
        belongId: this.space.id,
      },
    );
  }
  async payOrder(order: schema.XOrder): Promise<schema.XOrder | undefined> {
    return undefined;
  }
  async updateOrder(order: schema.XOrder): Promise<schema.XOrder | undefined> {
    return undefined;
  }
  async cancelOrder(orderId: string): Promise<boolean> {
    return false;
  }
  async completeOrder(orderId: string): Promise<boolean> {
    return false;
  }

  async createOrderDiscussionChat(sellerId: string, buyerId: string): Promise<any> {
    if (sellerId == null || buyerId == null) {
      throw new Error('供货方ID和下单方ID不能为空');
    }
    const groupName: string = '订单_' + this.key + '_沟通群';
    // TODO: 调用系统API创建群聊
    this.chatGroupId = 'generated_chat_group_id';
    return this.chatGroupId;
  }
  async hasDiscussionChat(sellerId: string, buyerId: string): Promise<boolean> {
    return true;
  }

  private splitOrder(data: schema.XThing): string {
    const splitField = this.mall.metadata.params?.splitField;
    if (!splitField || data['count'] === data[`T${splitField.propId}`]) {
      return JSON.stringify(data);
    }
    const splitCount = data[`T${splitField.propId}`] - data['count'];
    const result = SplitHandler.splitOrder(data, splitCount, `T${splitField.propId}`);
    if (Array.isArray(result.before) && result.before.length > 0) {
      return JSON.stringify(result.before[0]);
    }
    return JSON.stringify(data);
  }

  private calculateTotal(products: schema.XProduct[]): number {
    return products.reduce((p, n) => p + ((n.price || 0) * (n.carCount || 1) ?? 0), 0);
  }
  private calculateCount(products: schema.XProduct[]): number {
    return products.reduce((p, n) => p + (n.carCount || 1), 0);
  }
  private generateOrderNumber(): string {
    const EPOCH = BigInt(1577836800000);
    const machineId = BigInt(1);
    const dataCenterId = BigInt(1);
    const sequence = BigInt(Math.floor(Math.random() * 4096));
    const timestamp = BigInt(Date.now()) - EPOCH;
    const id =
      (timestamp << BigInt(22)) |
      (dataCenterId << BigInt(17)) |
      (machineId << BigInt(12)) |
      sequence;
    return id.toString();
  }
  private convertToDouble(target: Record<string, any>, fields: string[]): void {
    fields.forEach((field) => {
      if (target[field] !== undefined && !isNaN(target[field])) {
        // 转为数值并保留两位小数
        target[field] = parseFloat(parseFloat(target[field]).toFixed(2));
      }
    });
  }
}
